#include "main.h"


int main(int argc, char** argv) {
	// ifstream config_in;
	// ofstream result_out;

	string primaryFilename;		// master subgraph name
	string secondaryFilename;	// student subgraph name
	string resultOutFilename;	// result text file name
	string signatureFilename;	// result signature file name
	
	stringstream filenameBuilder;

	vector<int> subgraphsToTest;
	vector<pair<int, int> > resultSignature;

	EdgeList matchingSubgraphs;

	// read configuration
	ifstream config_in("config.txt", ifstream::in);
	int tmp;
	while(config_in.good()) {
		config_in >> tmp;
		subgraphsToTest.push_back(tmp);
	}
	config_in.close();
	
	if(argc == 1) {
		cout << "Enter name of primary (master) graph: ";
		cin >> primaryFilename;
	
		cout << "Enter name of secondary (student) graph: ";
		cin >> secondaryFilename;
	}
	else {
		primaryFilename = argv[1];
		secondaryFilename = argv[2];
	}	
	filenameBuilder << secondaryFilename << "_vs_" << primaryFilename << ".txt";
	resultOutFilename = filenameBuilder.str();
	ofstream result_out(resultOutFilename.c_str(), ofstream::out);
	
	// for each subgraph to test
	for(unsigned int i = 0; i < subgraphsToTest.size(); i++) {
		stringstream ss;
		string subgraphFilename;

		EdgeList primaryEdges;
		EdgeList secondaryEdges;

		// load subgraph data
		
		ss << primaryFilename << "_g" << subgraphsToTest.at(i) << ".txt";
		subgraphFilename = ss.str();
		ifstream primaryIn(subgraphFilename.c_str(), ifstream::in);

		ss.str("");
		ss.clear();

		ss << secondaryFilename << "_g" << subgraphsToTest.at(i) << ".txt";
		subgraphFilename = ss.str();
		ifstream secondaryIn(subgraphFilename.c_str(), ifstream::in);

		string tmp;
		// load primary
		while(primaryIn.good()) {
			vector<string> splitVec; // vector of vertex names on the current line (as they appear in file)
			vector<pair<string, string> > edgeGroup; // vector of edges
			getline(primaryIn, tmp);

			boost::split(splitVec, tmp, boost::is_any_of(" ,<->"), boost::token_compress_on);

			if(splitVec.size() == 1)
				continue;

			for(unsigned int i = 0; i < splitVec.size()-1; i+=2) { // the last element in the vector is a newline and is not used
				edgeGroup.push_back(pair<string, string>(splitVec[i], splitVec[i+1]));
			}

			primaryEdges.add(edgeGroup);
			//cout << splitVec.size()-1 << ":  " << splitVec[0] << ", " << splitVec[1];
		}
		primaryIn.close();

		// load secondary
		while(secondaryIn.good()) {
			vector<string> splitVec; // vector of vertex names on the current line (as they appear in file)
			vector<pair<string, string> > edgeGroup; // vector of edges
			getline(secondaryIn, tmp);

			boost::split(splitVec, tmp, boost::algorithm::is_any_of(" ,<->"), boost::token_compress_on);

			if(splitVec.size() == 1)
				continue;

			for(unsigned int i = 0; i < splitVec.size()-1; i+=2) { // the last element in the vector is a newline and is not used
				edgeGroup.push_back(pair<string, string>(splitVec[i], splitVec[i+1]));
			}

			secondaryEdges.add(edgeGroup);
		}
		secondaryIn.close();

		// compare the contents of primary and secondary and store matches in matchingSubgraphs[i]

		matchingSubgraphs = primaryEdges.compare(secondaryEdges);

		// output contents of matchingSubgraphs to file

		result_out << "common g" << subgraphsToTest.at(i) << " mappings:\n" << endl;
		matchingSubgraphs.printCombinations(result_out);
		result_out << endl << endl;

		resultSignature.push_back(pair<int, int>(subgraphsToTest.at(i), matchingSubgraphs.size()));
	}
	result_out.close();

	// signature file output

	filenameBuilder.str("");
	filenameBuilder.clear();

	filenameBuilder << secondaryFilename << "_vs_" << primaryFilename << "_signature.txt";
	signatureFilename = filenameBuilder.str();
	ofstream sigOut(signatureFilename.c_str(), ofstream::out);
	for(int i = 0; i < 30; i++) {
		int found = -1;
		for(unsigned int j = 0; j < resultSignature.size(); j++) {
			if(resultSignature.at(j).first == i) {
				found = j;
			}
		}
		if(found != -1)
			sigOut << resultSignature.at(found).second << ", ";
		else
			sigOut << "0, ";
	}
	sigOut.close();

	return 0;
}
